/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package dao

import (
	"fmt"
	"prim-server/common"
	"prim-server/model"

	"github.com/astaxie/beego/orm"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

type CreditDao struct {
	BaseDao
}

type ICreditDAo interface {
	SaveCreditInfo(creditAcount *model.Credit) error
	DeleteCreditInfo(userId string) error
	UpdateCreditInfo(creditAcount *model.Credit) error
	GetCreditInfo(queryParameter *common.QueryCreditDetail) (creditAcounts []*model.Credit, totalCount int, err error)
}

func GetCreditDao() ICreditDAo {
	dao := &CreditDao{}
	dao.Init()
	return dao
}

func (cd *CreditDao) SaveCreditInfo(creditAcount *model.Credit) error {
	if creditAcount == nil {
		return nil
	}
	_, err := cd.O.Insert(creditAcount)
	if err != nil {
		return errors.Errorf("SaveCreditInfo error: %v, userId: %s", err, creditAcount.UserId)
	}
	return nil
}

func (cd *CreditDao) DeleteCreditInfo(userId string) error {
	if len(userId) == 0 {
		return nil
	}
	creditAcount := new(model.Credit)
	creditAcount.UserId = userId
	_, err := cd.O.Delete(creditAcount, "user_id")
	if err != nil {
		return errors.Errorf("DeleteCreditInfo error: %v, userId: %s", err, userId)
	}
	return nil
}
func (cd *CreditDao) UpdateCreditInfo(creditAcount *model.Credit) error {
	if creditAcount == nil {
		return nil
	}
	_, err := cd.O.Update(creditAcount)
	if err != nil {
		return errors.Errorf("UpdateCreditInfo error: %v, userId: %s", err, creditAcount.UserId)
	}
	return nil
}
func (cd *CreditDao) GetCreditInfo(queryParameter *common.QueryCreditDetail) (creditAcounts []*model.Credit, totalCount int, err error) {
	if queryParameter == nil {
		return nil, 0, nil
	}
	recode := cd.O.QueryTable(&model.Credit{})
	finalCondition := orm.NewCondition()
	if queryParameter.UserId != nil && len(queryParameter.UserId) > 0 {
		finalCondition = finalCondition.And("user_id__in", queryParameter.UserId)
	}
	if queryParameter.CreditStatus != nil && len(queryParameter.CreditStatus) > 0 {
		finalCondition = finalCondition.And("credit_status__in", queryParameter.CreditStatus)
	}
	if queryParameter.ExpireTimeBegin != nil && queryParameter.ExpireTimeTimeEnd != nil {
		expireTimeCondition := orm.NewCondition()
		expireTimeCondition = expireTimeCondition.And("expire_time__gte", cd.ConvertToUTC(*queryParameter.ExpireTimeBegin)).And("expire_time__lte", cd.ConvertToUTC(*queryParameter.ExpireTimeTimeEnd))
		finalCondition = finalCondition.AndCond(expireTimeCondition)
	}
	if queryParameter.Currency != nil {
		finalCondition = finalCondition.And("currency", *queryParameter.Currency)
	}
	offset, pageSize := cd.GetOffsetAndPageSize(queryParameter.Page, queryParameter.PageSize)
	recode = recode.SetCond(finalCondition)
	totalCount64, err := recode.Count()
	if err != nil {
		return nil, 0, errors.Errorf("GetCreditInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	totalCount = cast.ToInt(totalCount64)
	_, err = recode.Offset(offset).Limit(pageSize).All(&creditAcounts)
	if err != nil {
		if err == orm.ErrNoRows {
			//not found
			return nil, 0, nil
		}
		//found error
		return nil, 0, errors.Errorf("GetCreditInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	return creditAcounts, totalCount, nil
}
